package net.expectx.pay.rpc.service.impl;

import net.expectx.common.single.base.BaseConstants;
import net.expectx.common.single.base.BaseResult;
import net.expectx.common.single.base.BaseServiceImpl;
import net.expectx.common.single.util.AesUtil;
import net.expectx.pay.dao.bean.ProductOrderPaymentRecord;
import net.expectx.pay.dao.bean.ProductOrderPaymentRecordExample;
import net.expectx.pay.dao.mapper.MerchantApplicationMapper;
import net.expectx.pay.dao.mapper.PaymentChannelMapper;
import net.expectx.pay.dao.mapper.ProductOrderHeaderMapper;
import net.expectx.pay.dao.bean.ProductOrderHeader;
import net.expectx.pay.dao.mapper.ProductOrderPaymentRecordMapper;
import net.expectx.pay.rpc.api.ProductOrderHeaderService;
import net.expectx.pay.dao.bean.ProductOrderHeaderExample;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * ProductOrderHeaderService实现
 * @author lijian
 * @date 2019/7/4
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProductOrderHeaderServiceImpl extends BaseServiceImpl<ProductOrderHeader, ProductOrderHeaderExample> implements ProductOrderHeaderService {

    private static final Logger LOGGER = Logger.getLogger(ProductOrderHeaderServiceImpl.class);

    @Autowired
    ProductOrderHeaderMapper productOrderHeaderMapper;
    @Autowired
    ProductOrderPaymentRecordMapper productOrderPaymentRecordMapper;
    @Autowired
    private DataSourceTransactionManager transactionManager;
    @Autowired
    private MerchantApplicationMapper merchantApplicationMapper;
    @Autowired
    private PaymentChannelMapper paymentChannelMapper;
    public BaseResult createOrder(Map<String,String>params ){
        String merchantNo=params.get("merchantNo");
        String applicationNo=params.get("applicationNo");
        String merchantOrderId=params.get("merchantOrderId");
        String orderName=params.get("orderName");
        String orderDesc=params.get("orderDesc");
        String orderDate=params.get("orderDate");
        String currencyUom=params.get("currencyUom");
        String tradeAmount=params.get("tradeAmount");

        /**
         * 创建订单
         */
        ProductOrderHeader productOrderHeader = new ProductOrderHeader();
        productOrderHeader.setMerchantNo(merchantNo);
        productOrderHeader.setAgentNo(applicationNo);
        productOrderHeader.setMerchantOrderId(merchantOrderId);
        productOrderHeader.setOrderName(orderName);
        productOrderHeader.setOrderDesc(orderDesc);
        productOrderHeader.setOrderDate(Long.valueOf(orderDate));
        productOrderHeader.setCurrencyUom(currencyUom);
        productOrderHeader.setGrandTotal(new BigDecimal(tradeAmount));
        if (params.containsKey("notifyUrl")){
            String notifyUrl=params.get("notifyUrl");
            productOrderHeader.setNotifyUrl(notifyUrl);
        }
        if (params.containsKey("channel")){
            String channelId=params.get("channel");
            productOrderHeader.setChannelId(Long.valueOf(channelId));
        }

        productOrderHeader.setOrderType("1");
        BaseResult baseResult = createOrder(productOrderHeader);
        return baseResult;
    }
    @Override
    public BaseResult createOrder(ProductOrderHeader productOrderHeader) {
        ProductOrderHeader orderHeader=null;
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            ProductOrderHeaderExample orderHeaderExample=new ProductOrderHeaderExample();
            ProductOrderHeaderExample.Criteria criteria=orderHeaderExample.createCriteria();
            criteria.andMerchantNoEqualTo(productOrderHeader.getMerchantNo());
            criteria.andMerchantOrderIdEqualTo(productOrderHeader.getMerchantOrderId());
            List<ProductOrderHeader>orderHeaders=productOrderHeaderMapper.selectByExample(orderHeaderExample);
            if (orderHeaders.isEmpty()){
                SimpleDateFormat simpleDateFormat;
                simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                Date date = new Date();
                String str = simpleDateFormat.format(date);
                Random random = new Random();
                int ranMum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
                String orderId = "EX"+ranMum + str;
                ranMum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
                orderId = orderId+ranMum;
                productOrderHeader.setOrderId(orderId);
                productOrderHeader.setGmtModified(System.currentTimeMillis());
                productOrderHeader.setGmtCreate(System.currentTimeMillis());
                productOrderHeader.setOrderStatus("0");
                int i=productOrderHeaderMapper.insertSelective(productOrderHeader);
                if (i == 0) {
                    throw new Exception();
                }else{
                    ProductOrderPaymentRecord productOrderPaymentRecord=new ProductOrderPaymentRecord();
                    productOrderPaymentRecord.setOrderId(orderId);
                    productOrderPaymentRecord.setGmtModified(System.currentTimeMillis());
                    productOrderPaymentRecord.setGmtCreate(System.currentTimeMillis());
                    productOrderPaymentRecord.setPayStatus("0");
                    productOrderPaymentRecord.setTotalFee(new BigDecimal(0));
                    productOrderPaymentRecord.setRecordId(UUID.randomUUID().toString().replace("-",""));
                    productOrderPaymentRecordMapper.insertSelective(productOrderPaymentRecord);
                    orderHeader=productOrderHeader;
                }
            }else{
                orderHeader=orderHeaders.get(0);
            }
            transactionManager.commit(status);
            return new BaseResult(true, "订单创建成功", orderHeader);
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback(status);
            return new BaseResult(false, "系统错误:" + e.getLocalizedMessage(), null);
        }
    }

    @Override
    public Map<String, Object> findPageByStrWhere(Integer pageIndex, Integer pageSize,String merchantNo, String tradeNo, String orderId, String endTime2, String endTime1, String startTime2, String startTime1, String grandTotal, String merchantOrderId, String payStatus, String orderType, String merchantApplication, String paymentChannel,String todayOrder, String strOrder)  {

        String strWhere = " is_deleted=0";
        if (StringUtils.isNotBlank(startTime1) && StringUtils.isNotBlank(endTime1)) {
            try {
                strWhere += " and order_date > " + getLongTime(startTime1 )+ " and order_date<" + getLongTime(endTime1);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if (StringUtils.isNotBlank(startTime2) && StringUtils.isNotBlank(endTime2)) {
            ProductOrderPaymentRecordExample productOrderPaymentRecordExample = new ProductOrderPaymentRecordExample();
            ProductOrderPaymentRecordExample.Criteria criteria = productOrderPaymentRecordExample.createCriteria();
            criteria.andIsDeletedEqualTo(BaseConstants.NO);
            try {
                criteria.andFinishTimeBetween(getLongTime(startTime2),getLongTime(endTime2));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            List<ProductOrderPaymentRecord> productOrderPaymentRecords = productOrderPaymentRecordMapper.selectByExample(productOrderPaymentRecordExample);
            if(!productOrderPaymentRecords.isEmpty()){
            try {
                strWhere += "  and   order_id in( select order_id from product_order_payment_record where finish_time > " + getLongTime(startTime2 )+ " and finish_time <" + getLongTime(endTime2 )+ ")";
            } catch (ParseException e) {
                e.printStackTrace();
            }}else{
                strWhere += "  and  1=2";
            }

        }
        if (StringUtils.isNotBlank(merchantNo)&&!merchantNo.equals("0")) {
                strWhere += "  and    merchant_no  = '"+merchantNo+"'";
        }
        if (StringUtils.isNotBlank(tradeNo)) {
            ProductOrderPaymentRecordExample productOrderPaymentRecordExample = new ProductOrderPaymentRecordExample();
            ProductOrderPaymentRecordExample.Criteria criteria = productOrderPaymentRecordExample.createCriteria();
            criteria.andIsDeletedEqualTo(BaseConstants.NO);
            criteria.andTradeNoLike("%" + tradeNo + "%");
            List<ProductOrderPaymentRecord> productOrderPaymentRecords = productOrderPaymentRecordMapper.selectByExample(productOrderPaymentRecordExample);
            if(!productOrderPaymentRecords.isEmpty()){
                String orderIds = "";
                for (ProductOrderPaymentRecord productOrderPaymentRecord : productOrderPaymentRecords) {
                    orderIds += productOrderPaymentRecord.getOrderId() + ",";
                }
                orderIds = orderIds.substring(0, orderIds.length() - 1);
                strWhere += "  and    FIND_IN_SET( order_id,'"+orderIds+"')";
            }else{
                strWhere += "  and  1=2";
            }
        }
        if (StringUtils.isNotBlank(merchantOrderId)) {
            strWhere += "  and    merchant_order_id like '%" + merchantOrderId + "%'";

        }
        if (StringUtils.isNotBlank(grandTotal)) {
            strWhere += "  and    grand_total = " + grandTotal + "";

        }
        if (StringUtils.isNotBlank(orderType)) {
            strWhere += "  and    order_type = " + orderType;
        }
        /**
         * 1:今日交易总数 2:交易成功总数
         */
        if ("1".equals(todayOrder)){
            long nowTime =System.currentTimeMillis();
            long todayStartTime = nowTime - (nowTime + TimeZone.getDefault().getRawOffset())% (1000*3600*24);
            long tomorrowStartTime = todayStartTime+(1000*3600*24);
            strWhere += "  and    order_date >= " + todayStartTime +" and order_date <= "+tomorrowStartTime;
        }else if ("2".equals(todayOrder)){
            long nowTime =System.currentTimeMillis();
            long todayStartTime = nowTime - (nowTime + TimeZone.getDefault().getRawOffset())% (1000*3600*24);
            long tomorrowStartTime = todayStartTime+(1000*3600*24);
            strWhere += " and order_status = 2  and    order_date >= " + todayStartTime +" and order_date <= "+tomorrowStartTime;
        }
        if (StringUtils.isNotBlank(payStatus)) {
            ProductOrderPaymentRecordExample productOrderPaymentRecordExample = new ProductOrderPaymentRecordExample();
            ProductOrderPaymentRecordExample.Criteria criteria = productOrderPaymentRecordExample.createCriteria();
            criteria.andIsDeletedEqualTo(BaseConstants.NO);
            criteria.andPayStatusEqualTo(payStatus);
            List<ProductOrderPaymentRecord> productOrderPaymentRecords = productOrderPaymentRecordMapper.selectByExample(productOrderPaymentRecordExample);

            if(!productOrderPaymentRecords.isEmpty()){
                String orderIds = "";
                for (ProductOrderPaymentRecord productOrderPaymentRecord : productOrderPaymentRecords) {
                    orderIds += productOrderPaymentRecord.getOrderId() + ",";
                }
                orderIds = orderIds.substring(0, orderIds.length() - 1);
                strWhere += "  and    FIND_IN_SET( order_id,'"+orderIds+"')";
            }else{
                strWhere += "  and  1=2";
            }
        }
        if (StringUtils.isNotBlank(orderId)) {
            strWhere += "  and    order_id like '%" + orderId + "%'";
        }
        if (StringUtils.isNotBlank(paymentChannel)) {
            ProductOrderPaymentRecordExample productOrderPaymentRecordExample = new ProductOrderPaymentRecordExample();
            ProductOrderPaymentRecordExample.Criteria criteria = productOrderPaymentRecordExample.createCriteria();
            criteria.andIsDeletedEqualTo(BaseConstants.NO);
            criteria.andChannelPaywayEqualTo(paymentChannel);
            List<ProductOrderPaymentRecord> productOrderPaymentRecords = productOrderPaymentRecordMapper.selectByExample(productOrderPaymentRecordExample);
            if (!productOrderPaymentRecords.isEmpty()) {
                String orderIds = "";
                for (ProductOrderPaymentRecord productOrderPaymentRecord : productOrderPaymentRecords) {
                    orderIds += productOrderPaymentRecord.getOrderId() + ",";
                }
                orderIds = orderIds.substring(0, orderIds.length() - 1);
                strWhere += "  and    FIND_IN_SET( order_id,'"+orderIds+"')";

            }else{
                strWhere += "  and  1=2";
            }
        }
        if (StringUtils.isNotBlank(merchantApplication)) {
            strWhere += "  and    merchant_no in( select merchant_no from merchant_application where id = " + merchantApplication + ")";
        }
        String order = "";
        if (StringUtils.isNotBlank(strOrder)) {
            String[] split = strOrder.split(",");
            order +=split[0] +" "+ split[1];
        }
        Map<String, Object> map = new HashMap<>();
        List<ProductOrderHeader> productOrderHeaders= productOrderHeaderMapper.findByPage(pageIndex, pageSize, strWhere, order);
        BigDecimal sum = new BigDecimal("0");
        BigDecimal serviceFee= new BigDecimal("0");
        BigDecimal settlementTotal= new BigDecimal("0");
        for (ProductOrderHeader productOrderHeader : productOrderHeaderMapper.findByPage(pageIndex, 0, strWhere, order)) {
            sum = sum.add(productOrderHeader.getGrandTotal());
            if (null != productOrderHeader.getServiceFee()) {
                serviceFee = serviceFee.add(productOrderHeader.getServiceFee());
            }
            if ("1".equals(productOrderHeader.getOrderStatus())) {
                settlementTotal = settlementTotal.add(productOrderHeader.getGrandTotal());
            }
        }
        int total = productOrderHeaderMapper.count(strWhere);
        map.put("productOrderHeaders", productOrderHeaders);
        map.put("total", total);
        map.put("sum", sum);
        map.put("serviceFee", serviceFee);
        map.put("settlementTotal", settlementTotal);
        return map;
    }


    @Override
    public int count(String strWhere) {
        return productOrderHeaderMapper.count(strWhere);
    }

    @Override
    public List<ProductOrderHeader> selectByWeek() {
        return productOrderHeaderMapper.selectByWeek();
    }

    private static Long getLongTime(String time)throws ParseException {
        DateFormat bf = new SimpleDateFormat("yyyy-MM-dd");//多态
        return bf.parse(time).getTime();
    }


}
